package com.piggy.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.piggy.common.core.constant.SecurityConstants;
import com.piggy.common.core.utils.PageUtils;
import com.piggy.common.core.web.domain.AjaxResult;
import com.piggy.common.core.web.page.PagePlus;
import com.piggy.common.core.web.page.TableDataInfo;
import com.piggy.common.satoken.utils.SecurityUtils;
import com.piggy.oss.cloud.OSSFactory;
import com.piggy.oss.utils.FileUploadUtils;
import com.piggy.system.api.bo.OssFileUploadBo;
import com.piggy.system.api.domain.SysOss;
import com.piggy.system.domain.bo.SysOssAddBo;
import com.piggy.system.domain.bo.SysOssEditBo;
import com.piggy.system.domain.bo.SysOssQueryBo;
import com.piggy.system.domain.vo.SysOssVo;
import com.piggy.system.mapper.SysOssMapper;
import com.piggy.system.service.ISysOssService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import static com.piggy.common.core.utils.file.MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION;


/**
 * 文件上传Service业务层处理
 *
 * @author piggy
 * @date 2021-07-20
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysOssServiceImpl extends ServiceImpl<SysOssMapper, SysOss> implements ISysOssService {

    @Override
    public SysOssVo queryById(Long id){
        return getVoById(id, SysOssVo.class);
    }

    @Override
    public TableDataInfo<SysOssVo> queryPageList(SysOssQueryBo bo) {
        PagePlus<SysOss, SysOssVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), SysOssVo.class);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<SysOssVo> queryList(SysOssQueryBo bo) {
        return listVo(buildQueryWrapper(bo), SysOssVo.class);
    }

    private LambdaQueryWrapper<SysOss> buildQueryWrapper(SysOssQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysOss> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getId() != null, SysOss::getId, bo.getId());
        lqw.eq(StrUtil.isNotBlank(bo.getFileType()), SysOss::getFileType, bo.getFileType());
        lqw.like(StrUtil.isNotBlank(bo.getName()), SysOss::getName, bo.getName());
        lqw.like(StrUtil.isNotBlank(bo.getOriginName()), SysOss::getOriginName, bo.getOriginName());
        lqw.like(StrUtil.isNotBlank(bo.getPath()), SysOss::getPath, bo.getPath());
        lqw.eq(StrUtil.isNotBlank(bo.getStatus()), SysOss::getStatus, bo.getStatus());
        return lqw;
    }

    @Override
    public Boolean insertByAddBo(SysOssAddBo bo) {
        SysOss add = BeanUtil.toBean(bo, SysOss.class);
        validEntityBeforeSave(add);
        return save(add);
    }

    @Override
    public Boolean updateByEditBo(SysOssEditBo bo) {
        SysOss update = BeanUtil.toBean(bo, SysOss.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(SysOss entity){
        //TODO 做一些数据校验,如唯一约束
		baseMapper.insert(entity);
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

	@SneakyThrows
	@Override
	public SysOss uploadFileToCLoud(MultipartFile file) {
		//校验文件大小类型
		FileUploadUtils.assertAllowed(file,DEFAULT_ALLOWED_EXTENSION);
		//上传文件后缀
		String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
		//文件上传返回url
		String path = OSSFactory.build().uploadSuffix(file.getBytes(), suffix);

//		chainService.getChainId(path, SecurityConstants.INNER);
//		chainService.getChainId(path, SecurityConstants.TOKENINNER);
        String hashCode = DigestUtil.sha256Hex(file.getBytes()).toString();
        Long userId = 0L;
        if (SecurityUtils.isPassword()) {
            userId = SecurityUtils.getUserId();
        }

		return saveLog(file,path);
	}

	@SneakyThrows
	@Override
	public SysOss uploadFileToCLoud(MultipartFile file, String path) {
		//校验文件大小类型
		FileUploadUtils.assertAllowed(file,DEFAULT_ALLOWED_EXTENSION);
		//文件上传返回url
		path = OSSFactory.build().upload(file.getBytes(), path);

		return saveLog(file,path);
	}

	@SneakyThrows
	private SysOss saveLog(MultipartFile file, String path) {
		//大小
		Long size = file.getSize();
		//文件名
		String originName = file.getOriginalFilename();
		//hash256
		String hashCode = DigestUtil.sha256Hex(file.getBytes());
		//文件类型
		String extensionName = FileUploadUtils.getExtension(file);
		SysOss sysOss = new SysOss();
		sysOss.setFileType(extensionName);
		sysOss.setOriginName(originName);
		sysOss.setPath(path);
		sysOss.setName(originName);
		sysOss.setUrl(path);
		sysOss.setValue(hashCode);
		sysOss.setSize(size);
		sysOss.setCreateBy("admin");

		String url = OSSFactory.build().buildUrl(path);

		validEntityBeforeSave(sysOss);
		sysOss.setUrl(url);
		return sysOss;
	}

	@Override
	public void delCloudFile(String objectName) {
    	OSSFactory.build().delFile(objectName);
	}

    @Override
    public AjaxResult getSysOssById(Long id) {

        return AjaxResult.success(queryById(id));
    }

    @Override
    public SysOss uploadToCloud(OssFileUploadBo bo) {
        //校验文件大小类型
//        FileUploadUtils.assertAllowed(file,DEFAULT_ALLOWED_EXTENSION);
//        //上传文件后缀
//        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String fileName = bo.getFileName();
        String content = bo.getContent();
        byte[] bytes = Base64Utils.decodeFromString(content);
        //文件上传返回url
        String path = OSSFactory.build().uploadSuffix(bytes, fileName);

//		chainService.getChainId(path, SecurityConstants.INNER);
//		chainService.getChainId(path, SecurityConstants.TOKENINNER);
        String hashCode = DigestUtil.sha256Hex(content).toString();
        Long userId = 0L;
        if (SecurityUtils.isPassword()) {
            userId = SecurityUtils.getUserId();
        }

        return saveContent(bytes,path,fileName);
    }

    private SysOss saveContent(byte[] content, String path,String name) {
        //大小
        Long size =Long.valueOf(content.length);
        //文件名
        String originName = name;
        //hash256
        String hashCode = DigestUtil.sha256Hex(content);
        //文件类型
        String extensionName = name;
        SysOss sysOss = new SysOss();
        sysOss.setFileType(extensionName);
        sysOss.setOriginName(originName);
        sysOss.setPath(path);
        sysOss.setName(originName);
        sysOss.setUrl(path);
        sysOss.setValue(hashCode);
        sysOss.setSize(size);
        sysOss.setCreateBy("admin");

        String url = OSSFactory.build().buildUrl(path);

        validEntityBeforeSave(sysOss);
        sysOss.setUrl(url);
        return sysOss;
    }
}
